﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;

namespace Model
{
	public class CableTrayBatchCodeHelper
	{
		public CableTrayBatchCodeHelper(UIDocument uiDoc, string m_code, CableTrayBatchCodeMode mode, bool lev, bool dir, decimal m_index)
		{
			this.doc = uiDoc.ActiveView.Document;
			this.sel = uiDoc.Selection;
			this.code = m_code;
			this.codeMode = mode;
			this.selLeval = lev;
			this.selDir = dir;
			this.index = m_index;
		}

		public void CableTrayBatchCode()
		{
			if (this.codeMode == CableTrayBatchCodeMode.BatchSel)
			{
				this.CableTrayBatchSelCode();
				return;
			}
			if (this.codeMode == CableTrayBatchCodeMode.Connection)
			{
				this.CableTrayConnectionCode();
				return;
			}
			if (this.codeMode == CableTrayBatchCodeMode.All)
			{
				this.CableTrayAllCode();
			}
		}

		private void CableTrayBatchSelCode()
		{
			try
			{
				IList<Reference> list = this.sel.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, this.cableTraySelectionFilter, "请选择要编码的桥架");
				if (list.Count != 0)
				{
					List<CableTray> list2 = (from pickObj in list
					select this.doc.GetElement(pickObj.ElementId) as CableTray).ToList<CableTray>();
					Common.AddCableTrayParam(this.doc, list2[0]);
					this.SetCableTraysParam(list2);
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
		}

		private void CableTrayConnectionCode()
		{
			try
			{
				Reference reference = this.sel.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, this.cableTraySelectionFilter, "请选择一要编码的桥架");
				CableTray cableTray = this.doc.GetElement(reference) as CableTray;
				Common.AddCableTrayParam(this.doc, cableTray);
				List<CableTray> list = (from ct in new PathwayCheck().GetPathwayDevices(cableTray, SearchDeviceType.CableTray)
				select ct as CableTray).ToList<CableTray>();
				Common.AddCableTrayParam(this.doc, list[0]);
				this.SetCableTraysParam(list);
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
			}
		}

		private void CableTrayAllCode()
		{
			List<CableTray> list = (from ct in RevitFilter.GetElementsOfType(this.doc, typeof(CableTray))
			select ct as CableTray).ToList<CableTray>();
			if (list.Count > 0)
			{
				Common.AddCableTrayParam(this.doc, list[0]);
				this.SetCableTraysParam(list);
			}
		}

		private void SetCableTraysParam(IList<CableTray> cableTrays)
		{
			bool flag = true;
			int num = 0;
			List<CableTray> list = new List<CableTray>();
			List<Element> list2 = RevitFilter.GetElementsOfType(this.doc, typeof(Level), BuiltInCategory.OST_Levels).ToElements().ToList<Element>();
			if (list2.Count == 1)
			{
				list = cableTrays.ToList<CableTray>();
			}
			else
			{
				Dictionary<double, double> levelsByOrder = this.GetLevelsByOrder(list2);
				List<double> list3 = new List<double>(levelsByOrder.Keys);
				for (int i = 0; i < levelsByOrder.Count; i++)
				{
					List<CableTray> temp = new List<CableTray>();
					foreach (CableTray cableTray in cableTrays)
					{
						ElementId elementId = cableTray.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsElementId();
						double elevation = (this.doc.GetElementById(elementId) as Level).Elevation;
						double num2 = cableTray.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble();
						double num3 = elevation + num2;
						if (i == levelsByOrder.Count - 1)
						{
							if (num3 >= list3[i])
							{
								temp.Add(cableTray);
							}
						}
						else if (num3 >= list3[i] && num3 < levelsByOrder[list3[i]])
						{
							temp.Add(cableTray);
						}
					}
					List<CableTray> list4 = new List<CableTray>();
                    //Func<Element, bool> <>9__0;
					foreach (CableTray cableTray2 in temp)
					{
						bool flag2 = true;
						using (List<CableTray>.Enumerator enumerator3 = list4.GetEnumerator())
						{
							while (enumerator3.MoveNext())
							{
								if (enumerator3.Current.Id.IntegerValue == cableTray2.Id.IntegerValue)
								{
									flag2 = false;
									break;
								}
							}
						}
						if (flag2)
						{
							IEnumerable<Element> pathwayDevices = new PathwayCheck().GetPathwayDevices(cableTray2, SearchDeviceType.CableTray);
							Func<Element, bool> predicate;
                            //if ((predicate = <>9__0) == null)
                            //{
                            //    predicate = (<>9__0 = delegate(Element c)
                            //    {
                            //        using (List<CableTray>.Enumerator enumerator5 = temp.GetEnumerator())
                            //        {
                            //            while (enumerator5.MoveNext())
                            //            {
                            //                if (enumerator5.Current.Id.IntegerValue == c.Id.IntegerValue)
                            //                {
                            //                    return true;
                            //                }
                            //            }
                            //        }
                            //        return false;
                            //    });
                            //}
                            //List<CableTray> list5 = (from ct in pathwayDevices.Where(predicate)
                            //select ct as CableTray).ToList<CableTray>();
                            //if (list5.Count > 0)
                            //{
                            //    list4.AddRange(list5);
                            //}
						}
					}
					list.AddRange(list4);
				}
			}
			foreach (CableTray cableTray3 in list)
			{
				string text = this.code;
				if (this.selLeval)
				{
					string value = cableTray3.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsValueString();
					int startIndex = text.IndexOf("?");
					text = text.Remove(startIndex, 1).Insert(startIndex, value);
				}
				if (this.selDir)
				{
					int startIndex2 = text.LastIndexOf("?");
					text = text.Remove(startIndex2, 1).Insert(startIndex2, this.GetCableTrayDirection(cableTray3));
				}
				if (!flag)
				{
					if (this.index == -1m)
					{
						text = this.CheckStartEncoding(text, ref num);
					}
					else
					{
						object arg = text.Substring(0, text.LastIndexOf("-") + 1);
						decimal num4 = ++this.index;
						this.index = num4;
						text = (string)arg + num4;
						text = this.NotCheckStartEncoding(text);
					}
				}
				else
				{
					if (this.index == -1m)
					{
						text = this.CheckStartEncoding(text, ref num);
					}
					else
					{
						text = this.NotCheckStartEncoding(text);
					}
					flag = false;
				}
				bool flag3 = false;
				foreach (Element element in this.noNumbers)
				{
					if (cableTray3.Id.IntegerValue == element.Id.IntegerValue)
					{
						flag3 = true;
						break;
					}
				}
				if (!flag3)
				{
					cableTray3.GetParameter("编号").Set(text);
				}
				else if (this.index == -1m)
				{
					num--;
				}
				else
				{
					this.index = --this.index;
				}
			}
		}

		private string CheckStartEncoding(string ctCode, ref int increment)
		{
			object arg = ctCode;
			object arg2 = "-";
			int num = increment + 1;
			increment = num;
            ctCode = (string)arg + (string)arg2 + num;
			if (this.CodeIsRepeat(this.doc, ctCode))
			{
				do
				{
					object arg3 = ctCode.Substring(0, ctCode.LastIndexOf("-") + 1);
					num = increment + 1;
					increment = num;
                    ctCode = (string)arg3 + num;
				}
				while (this.CodeIsRepeat(this.doc, ctCode));
				return ctCode;
			}
			return ctCode;
		}

		private string NotCheckStartEncoding(string ctCode)
		{
			if (this.CodeIsRepeat(this.doc, ctCode))
			{
				do
				{
					object arg = ctCode.Substring(0, ctCode.LastIndexOf("-") + 1);
					decimal num = ++this.index;
					this.index = num;
                    ctCode = (string)arg + num;
				}
				while (this.CodeIsRepeat(this.doc, ctCode));
				return ctCode;
			}
			return ctCode;
		}

		private Dictionary<double, double> GetLevelsByOrder(List<Element> levels)
		{
			List<double> list = new List<double>();
			foreach (Element element in levels)
			{
				double elevation = (element as Level).Elevation;
				list.Add(elevation);
			}
			list = list.Distinct<double>().ToList<double>();
			list.Sort();
			Dictionary<double, double> dictionary = new Dictionary<double, double>();
			for (int i = 0; i < list.Count; i++)
			{
				dictionary.Add(list[i], list[i + 1]);
				if (i + 1 == list.Count - 1)
				{
					dictionary.Add(list[i + 1], list[i + 1]);
					break;
				}
			}
			return dictionary;
		}

		private string GetCableTrayDirection(CableTray ct)
		{
			HYCableTray<CableTray> hycableTray = new HYCableTray<CableTray>(ct);
			if (hycableTray.IsXAxis())
			{
				return "X";
			}
			if (hycableTray.IsYAxis())
			{
				return "Y";
			}
			if (hycableTray.IsZAxis())
			{
				return "Z";
			}
			return "T";
		}

		private bool CodeIsRepeat(Document doc, string code)
		{
			IList<Element> list = RevitFilter.GetElementsOfType(doc, typeof(CableTray)).ToElements();
			list = list.Where(delegate(Element r)
			{
				string text = r.GetParameter("编号").AsString();
				return !string.IsNullOrEmpty(text) && text == code;
			}).ToList<Element>();
			if (list.Count == 0)
			{
				return false;
			}
			foreach (Element item in list)
			{
				this.noNumbers.Add(item);
			}
			return true;
		}

		private Document doc;

		private Selection sel;

		private CableTrayBatchCodeMode codeMode;

		private ISelectionFilter cableTraySelectionFilter = new CableTrayFilter();

		private string code;

		private bool selDir;

		private bool selLeval;

		private decimal index;

		private List<Element> noNumbers = new List<Element>();
	}
}
